#include "tictactoe_duino.h" 
#include <EEPROM.h>

//############################################
//# Library functions	                     #
//############################################

/*
Physical board Layout:
 +----------------+  
 | 1.1 | 1.2 | 1.3| 
 |-----+-----+----|
 | 1.1 | 1.2 | 1.3|
 |-----+-----+----|
 | 1.1 | 1.2 | 1.3|
 +----------------+
 |  G  |
 +-----+
 
 Software board Layout:
 buttonNr and ledNr range from 0 to 9, where 0..8 are the play buttons/led and 9 is the game button/led
 The Game button/led can be used to start a game, choose a random starting player and/or show the current player. 
 +----------------+  
 |  0  |  1  |  2 | 
 |-----+-----+----|
 |  3  |  4  |  5 |
 |-----+-----+----|
 |  6  |  7  |  8 |
 +----------------+
 |  9  |
 +-----+
 
 COLOR: NONE, GREEN, RED, ORANGE     // available colors
 
 initialisation();                   // initialisation of the hardware, has to be done once in setup();
 int check_buttons();                // returns buttonNr
 void set_ledNr(lednr, COLOR);       // enables LED ledNr with color
*/

int player = 1;
int com = -1;
int board[9];
boolean playing = false;

int possibleWins = 8;

// these positions win
// when occupied from the same player
int wins [8][3] = {
    {0, 1, 2},
    {3, 4, 5},
    {6, 7, 8},
    {0, 3, 6},
    {1, 4, 7},
    {2, 5, 8},
    {0, 4, 8},
    {2, 4, 6}
  };

// Setup runs only once at startup
void setup() {
  
  Serial.begin(9600);
  // initialize hardware timing and I/O functionality to the board
  initialisation();
  reset();  
}

// starts a new game
void reset() {
  
  playing = true;
  player = 1;
  
  for (int i = 0; i < 9; i++) {
    
    set_ledNr(i, NONE);
    board[i] = 0;
  }
  
  //player = (byte) random(1,3);
}

// returns true if n is a terminal node
bool isTerminal(int n[]) {
  
  for (int i = 0; i < possibleWins; i++) {
    
    if ((n[wins[i][0]] != 0) && (n[wins[i][0]] == n[wins[i][1]]) && (n[wins[i][0]] == n[wins[i][2]])) {
      
      return true;
    }
  }
  
  for (int i = 0; i < 9; i++) {
    
    if (n[i] == 0) {
      
      return false;
    }
  }
  
  return true;
}

// returns the minimax value of a position
int minimax(int n[], int p, int* move) {
  
  //Serial.println("Hello");
  if (isTerminal(n)) {
    
    return valueOf(n);
  }
  
  int alpha, first = 1;
  
  for (int i = 0; i < 9; i++) {
  
    if (n[i] == 0) {
    
      n[i] = p;
      
      int foo;
      int newAlpha = minimax(n, opponentOf(p), &foo);
      
      n[i] = 0;
      
      if (first) {
       
        first = 0;
        alpha = newAlpha;
        *move = i;
        //Serial.println(*move);
      }
      else if ((p == 1) && (newAlpha > alpha)) {
        
        *move = i;
        alpha = newAlpha;
        //Serial.println(*move);
      }
      else if ((p == -1) && (newAlpha < alpha)) {
        
        *move = i;
        alpha = newAlpha;
        //Serial.println(*move);
        
      } 
    }
  }
  
  return alpha;
}

// returns the value of a board
// 1: player1 won the game
// 2: player2 won the game
// 0: no winner (yet)
int valueOf(int b[]) {
  
  // goes through all possible win positions
  // and if possible returns the winner
  for (int i = 0; i < possibleWins; i++) {
    
    int winner = b[wins[i][0]];
    
    if ((winner != 0) && (winner == b[wins[i][1]]) && (winner == b[wins[i][2]])) {
      
      return winner;
    }
  }
  
  return 0;
}

// advances the player to move next
void nextPlayer() {
  
  player = (player == 1) ? -1 : 1;
}

// returns the opponent of p
int opponentOf(int p) {
  
  return (p == 1) ? -1 : 1;
}

// loop() is a replacement for main()
void loop() {
  
  if (player == com) {
    
    //set_ledNr(9, ORANGE);
    
    int bar;
    
    //Serial.println(move);
    
    
    int val = minimax(board, player, &bar);
    
    Serial.println(bar);
    
    int color = (player == 1) ? GREEN : RED;
    
    board[bar] = player;
    set_ledNr(bar, color);
    
    
    nextPlayer();
    
  }
  
  
  else {
    
    int pressedButton = check_buttons();
    
    if (board[pressedButton] == 0) {
      
      int color = (player == 1) ? GREEN : RED;
      
      board[pressedButton] = player;
      set_ledNr(pressedButton, color);
      
      nextPlayer();
    }
  }
}










